This sample notebook is based on the experiment outlined in Chapter 15 of the book Computation and Programming in Python.
Hooke's Law suggests that the force associated with a spring when it is released is linearly related to the distance it has been compressed.
An experiment was conducted to capture data for a number of springs across various compression lengths. The indent of the experiment is demonstrate Hooke's Law by showing that the results of the experiment lie on a straight line. Yet experiment data tends not to be perfect so we expect the results to lie around a curved line not necessary on it.
Could we use the results to fit a model that will allow us to depict the linear premise posited by Hooke? Can we use a linear regression to solve the problem?
In [ ]:
def getData(fileName):
dataFile = open(fileName, 'r')
distances = []
masses = []
discardHeader = dataFile.readline()
for line in dataFile:
d, m = line.split(' ')
distances.append(float(d))
masses.append(float(m))
dataFile.close()
return (masses, distances)
getData('/resources/springData.txt')
In [ ]:
%matplotlib inline
In [ ]:
import pylab, random
def plotData(inputFile):
masses, distances = getData(inputFile)
masses = pylab.array(masses)
distances = pylab.array(distances)
forces = masses*9.81
pylab.plot(forces, distances, 'bo',
label = 'Measured displacements')
pylab.title('Measured Displacement of Spring')
pylab.xlabel('|Force| (Newtons)')
pylab.ylabel('Distance (meters)')
plotData('/resources/springData.txt')
In [ ]:
def fitData(inputFile):
masses, distances = getData(inputFile)
distances = pylab.array(distances)
masses = pylab.array(masses)
forces = masses*9.81
pylab.plot(forces, distances, 'bo',
label = 'Measured displacements')
pylab.title('Measured Displacement of Spring')
pylab.xlabel('|Force| (Newtons)')
pylab.ylabel('Distance (meters)')
#find linear fit
a,b = pylab.polyfit(forces, distances, 1)
predictedDistances = a*pylab.array(forces) + b
k = 1.0/a
pylab.plot(forces, predictedDistances,
label = 'Displacements predicted by\nlinear fit, k = '
+ str(round(k, 5)))
pylab.legend(loc = 'best')
fitData('/resources/springData.txt')
In [ ]:
def compareFitData(inputFile):
masses, distances = getData(inputFile)
distances = pylab.array(distances)
masses = pylab.array(masses)
forces = masses*9.81
pylab.plot(forces, distances, 'bo',
label = 'Measured displacements')
pylab.title('Measured Displacement of Spring')
pylab.xlabel('|Force| (Newtons)')
pylab.ylabel('Distance (meters)')
#find linear fit
a,b = pylab.polyfit(forces, distances, 1)
predictedDistances = a*pylab.array(forces) + b
k = 1.0/a
pylab.plot(forces, predictedDistances,
label = 'Displacements predicted by\nlinear fit, k = '
+ str(round(k, 5)))
#find cubic fit
a,b,c,d = pylab.polyfit(forces, distances, 3)
predictedDistances = a*(forces**3) + b*forces**2 + c*forces + d
pylab.plot(forces, predictedDistances, 'b:', label = 'cubic fit')
pylab.legend(loc = 'best')
compareFitData('/resources/springData.txt')
In [ ]:
def reduceToImprove(inputFile):
masses, distances = getData(inputFile)
distances = pylab.array(distances[:-6])
masses = pylab.array(masses[:-6])
forces = masses*9.81
pylab.plot(forces, distances, 'bo',
label = 'Measured displacements')
pylab.title('Measured Displacement of Spring')
pylab.xlabel('|Force| (Newtons)')
pylab.ylabel('Distance (meters)')
#find linear fit
a,b = pylab.polyfit(forces, distances, 1)
predictedDistances = a*pylab.array(forces) + b
k = 1.0/a
pylab.plot(forces, predictedDistances,
label = 'Displacements predicted by\nlinear fit, k = '
+ str(round(k, 5)))
#find cubic fit
a,b,c,d = pylab.polyfit(forces, distances, 3)
predictedDistances = a*(forces**3) + b*forces**2 + c*forces + d
pylab.plot(forces, predictedDistances, 'b:', label = 'cubic fit')
pylab.legend(loc = 'best')
reduceToImprove('/resources/springData.txt')
Based on the predictive modeling explored herein, we could conclude that we lack a sufficient sample set of experimental data to validate Hooke's Law.
The reader is encouraged to expand on this data exploration lesson by implementing additional modeling techniques discussed in Chapter 15 of the book Computation and Programming in Python.